Previous Book Contents Book Index Next

Inside Macintosh: Overview /
Chapter 6 - Windows


Creating Windows

The Venn Diagrammer application allows the user to have multiple document windows (that is, multiple Venn diagram windows) on the desktop at the same time. Each different document window probably displays a different syllogism. As a result, the application needs some way to keep track of each window's current settings.

A standard way to do this is to make use of the refCon field in the window record. The refCon field is reserved specifically for use by applications, which can set the field (using the SetWRefCon procedure) to any 4-byte value. Often, applications store a handle to an application-defined data structure that describes the window. This data structure is often known as a document record. Given the window pointer, you can retrieve that handle by calling the GetWRefCon function.

The sample code in this book uses a document record of type MyDocRec (shown in Listing 6-5) to store information about the current contents of a Venn diagram window.

Listing 6-5 The structure of a document record for the Venn Diagrammer application

TYPE MyDocRec =         {information for a document window}
   RECORD
      figure:           Integer;                {the figure of the syllogism}
      mood:             ARRAY[1..3] OF Integer; {the moods of the statements}
      terms:            ARRAY[1..3] OF Str31;   {the three terms}
      statusText:       Str255;                 {most recent status message}
      userSolution:     MyDiagramState;         {user's diagram state}
      realSolution:     MyDiagramState;         {answer's diagram state}
      isAnswerShowing:  Boolean;                {is the answer showing?}
      isExistImport:    Boolean;                {stmts imply exists subject?}
      needsAdjusting:   Boolean;                {diagram needs adjusting?}
   END;
   MyDocRecPtr = ^MyDocRec;
   MyDocRecHnd = ^MyDocRecPtr;
As you can see, the document record used by the Venn Diagrammer application contains fields that describe the current settings of the syllogism in the window, including the figure of the syllogism, the mood of each statement in the syllogism, and the terms used in those statements. The document record also contains fields that maintain information about the current appearance of the window, such as the status message most recently displayed in the window's status area (statusText field) and a Boolean value that indicates whether the answer is visible in the window (isAnswerShowing field). The Venn Diagrammer application uses that Boolean value to determine how to fill in the regions in the overlapping circles. If the value of isAnswerShowing is TRUE, the application displays the correct answer (encoded in the realSolution field); otherwise, the application displays the user's current answer (encoded in the userSolution field).

Note
The structure of the MyDiagramState data type is not shown in this book.
The MyDocRec data structure also contains two other fields containing Boolean values. These specify whether the statements that make up the syllogism are to be interpreted as having existential import or not, and whether the window needs to be checked for automatic adjustment.

IMPORTANT
If a Venn diagram window contained TextEdit fields or controls (such as radio buttons or scroll bars), the document record could be expanded to include handles to those items. Also, if a file were associated with the window, you'd want the document record to include information about that file. In a nutshell, the document record can contain all relevant information about the window that isn't contained in the window record.
The Venn Diagrammer application creates a document record every time it creates a document window, and it stores a handle to the document record in the refCon field of the window record. Listing 6-6 shows the DoCreateWindow routine, which creates a new document window. This function is called when the application is first launched and whenever the user chooses the New command from the File menu.

Listing 6-6 Creating a new Venn diagram window

FUNCTION DoCreateWindow: WindowPtr;
   VAR
      myPointer:  Ptr;
      myWindow:   WindowPtr;
      myHandle:   MyDocRecHnd;
BEGIN
   myPointer := NewPtr(sizeof(WindowRecord));
   IF myPointer = NIL THEN
      exit(DoCreateWindow);

   myWindow := GetNewWindow(rVennD, myPointer, WindowPtr(-1));
   IF myWindow <> NIL THEN
      BEGIN
         SetPort(myWindow);
         myHandle := MyDocRecHnd(NewHandleClear(sizeof(MyDocRec)));

         IF myHandle <> NIL THEN
            BEGIN
               HLockHi(Handle(myHandle));    {lock the data high in the heap}
               SetWRefCon(myWindow, LongInt(myHandle));
                                             {attach handle to window record}
               DoSetWindowTitle(myWindow);   {set the window title}

               {Define initial window settings.}
               WITH myHandle^^ DO
                  BEGIN
                     figure := 1;
                     mood[1] := 1;
                     mood[2] := 1;
                     mood[3] := 1;
                     isAnswerShowing := FALSE;
                     isExistImport := gGiveImport;
                  END;
               DoGetRandomTerms(myWindow);
               DoCalcAnswer(myWindow);

               {Position the window and display it.}
               DoPositionWindow(myWindow);
               ShowWindow(myWindow);

            END {IF myHandle <> NIL}
         ELSE
            BEGIN                         {couldn't get a data record}
               CloseWindow(myWindow);
               DisposePtr(Ptr(myWindow));
               myWindow := NIL;           {so pass back NIL}
            END;
      END;
   DoCreateWindow := myWindow;
END;
The DoCreateWindow function first attempts to allocate space in the heap for a window record by calling the Memory Manager's NewPtr function. If no space is available, DoCreateWindow exits and returns NIL to indicate that no new window was created. Otherwise, DoCreateWindow creates the new window, whose size and type are defined in a window resource of type rVennD.

CONST
   rVennD      = 131;         {resource ID of document window}
If the new window is successfully created, DoCreateWindow next tries to allocate space for a document record. Once again, if the space isn't available, DoCreateWindow takes care to dispose of the new window and return NIL to the calling routine. Otherwise, DoCreateWindow locks the handle to the document record high in the heap and attaches the document record to the window record by calling SetWRefCon.

Note
The document record data is locked at the top of the heap to help prevent heap fragmentation. See the chapter "Introduction to Memory Management" in Inside Macintosh: Memory for a discussion of when you need to lock data in the heap.
The DoCreateWindow function next sets up the window's title (by calling the application-defined procedure DoSetWindowTitle) and initializes some of the fields in the document record. Then DoCreateWindow calls two further application-defined procedures (DoGetRandomTerms and DoCalcAnswer) to initialize the terms field and the realSolution field of the document record. (As for the userSolution field, the NewHandleClear function, which sets all bytes in the block to 0, automatically initializes it to encode an empty diagram, according to a clever scheme.)

The application-defined procedure DoPositionWindow sets the original position of the new window according to the user's expectations and good human interface design. Then DoCreateWindow calls the Window Manager procedure ShowWindow to display the window. The ShowWindow procedure generates and update event for the newly displayed window, thereby causing the Venn Diagrammer application to draw the content region of the window.

Note
The procedure DoPositionWindow is not defined in this book. For a discussion of how to determine the position of a new window, see the chapter "Window Manager" in Inside Macintosh: Macintosh Toolbox Essentials.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
9 JUL 1996